package server.diffusion;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

import javax.vecmath.Quat4d;
import javax.vecmath.Vector3d;

public class MulticastDiffusionImpl implements MulticastDiffusion, Serializable {

	private static MulticastDiffusionImpl instance;
	
	private static final long serialVersionUID = -6431562754032461674L;

	private int diffusionPort;
	private String groupName;
	private InetAddress diffusionAdress;
	private transient MulticastSocket diffusionSocket;

	public static MulticastDiffusion instance(String groupName, int diffusionPort){
		if(instance==null) {
			instance = new MulticastDiffusionImpl(groupName, diffusionPort);
		}
		return instance;
	}
	
	private MulticastDiffusionImpl(String groupName, int diffusionPort) {
		this.diffusionPort = diffusionPort;
		this.groupName = groupName;

		System.out.println ("Diffuseur sur le port " + diffusionPort + " � destination du groupe " + groupName);

		try {
			diffusionAdress = InetAddress.getByName(groupName);
			diffusionSocket = new MulticastSocket(diffusionPort);
			diffusionSocket.setTimeToLive(64);
			diffusionSocket.setLoopbackMode(true);
		} 
		catch (IOException e) {
			e.printStackTrace () ;
		}

		System.out.println ("socket : " + diffusionSocket.getLocalPort() + " " + diffusionSocket.getInetAddress());
	}

	@Override
	public void diffuseMessage(String name, Vector3d position, Quat4d orientation, String geometry) {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		ObjectOutputStream objectOutputStream;
		
		try {
			objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
			objectOutputStream.writeObject(name);
			objectOutputStream.writeObject(position);
			objectOutputStream.writeObject(orientation);
			objectOutputStream.writeObject(geometry);
			//objectOutputStream.flush();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		
		DatagramPacket packet = new DatagramPacket (byteArrayOutputStream.toByteArray (), byteArrayOutputStream.toByteArray ().length, diffusionAdress, diffusionPort);
		try {
			diffusionSocket.send(packet);
		} 
		catch (IOException e) {
			e.printStackTrace () ;
		}
	}

	@Override
	public int getDiffusionPort () {
		return diffusionPort;
	}

	@Override
	public InetAddress getDiffusionAddress() {
		return diffusionAdress;
	}

	@Override
	public String getGroupName () {
		return groupName;
	}

}
